JavaアプリケーションからAmazon Kinesis Firehoseにログを直接出力する
Kinesis StreamとKinesis Firehoseは、フルマネージドなストリーミングサービスとして提供されており、大規模なデータの収集・処理に使うことができます。
その一つの活用法として、Kinesis Logback Appenderを紹介したいと思います。
Guardian社が開発しているLogbackのAppenderで、READMEの記載によるとawslabs/kinesis-log4j-appender: GithubのLogback実装とのことです。
READMEに記載の通り、Kinesis StreamとKinesis Firehoseの両方に対応しています。今回はFirehoseAppenderを利用してKinesis Firehoseにログを送信し、S3に出力されていることを確認します。
AWS側の設定
Kinesis Firehoseの作成手順詳細は、別記事にかかれていますのでそちらを併せて参照ください。
今回は以下の点を特筆する点として挙げておきます。
- Stream Nameは
logback-firehose
とした - Destinationには同じAWSアカウントにある適当なS3バケットを指定した
それ以外はデフォルトの設定でDelivery Streamを作成し、ステータスがACTIVEになることを確認します。
Javaアプリケーションの設定
まず、ライブラリのダウンロードをしましょう。私の環境ではGradleを使っているため、以下をbuild.gradle
に追加しました。
compile('com.gu:kinesis-logback-appender:1.4.0')
logback.xml
に以下の記載を足します。
<configuration> <appender name="KINESIS" class="com.gu.logback.appender.kinesis.FirehoseAppender"> <region>ap-northeast-1</region> <streamName>logback-firehose</streamName> <encoding>UTF-8</encoding> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%msg%n</pattern> </layout> </appender> <root level="DEBUG"> <appender-ref ref="KINESIS"/> </root> </configuration>
必須なのはregion
(またはendpoint
)とstreamName
です。その他、bufferSize
やmaxRetry
などのオプションもlogback.xml
から設定可能です。詳細はGithubのREADMEのサンプルを参照ください。
今回の例では、streamName
の設定値を上の手順で作成したlogback-firehose
としています。
実際にログを出力するアプリケーションコードはこんな感じで雑に書きました。Lombokの@Slf4j
アノテーションを利用しています。
@Slf4j public class KinesisLogRunner implements CommandLineRunner { @Override public void run(String... args) throws Exception { while(true) { log.debug("debug log"); log.info("info log"); log.warn("warn log"); log.error("error log"); Thread.sleep(1000L); } } }
動作確認
このJavaプログラムをしばらく流したままにしておき、先ほどKinesis FirehoseのDestinationとして登録したS3バケットにデータが登録されているかを確認してみましょう。
対象S3バケットのyyyy/mm/dd/hh
のPrefix以下に、Kinesis Firehoseからのデータが書き込まれていました!中身を見てみましょう。中身の確認はAWS CLIを利用すると簡単に行なえます。
$ aws s3 cp s3://sample-firehose-bucket/2017/10/23/07/logback-firehose-1-2017-10-23-07-33-05-ce946ccf-f2c2-47a8-8aa1-39bf5183fff0 - | head -n 10 info log warn log debug log error log debug log warn log error log info log error log
今回は簡易化のためにMessageのみをFirehoseに送るようにしていますが、当然LogbackのLayout次第で送る内容は調整可能です。
Logbackに設定を追加するだけで、簡単にFirehoseへとログを送ることができました!
まとめ
アプリケーション開発をする中で(気づかないうちに)規模・容量が大きくなっているのがアプリケーションログではないでしょうか。様々なログが肥大化してディスクフルになった、という経験はサーバ運用に関わった方は誰しも持っているかと思います。
サーバのクラウド化が進み、近年のコンテナ技術の流行もあり、ログはサーバ上に吐き出したままにしてはいけない。必ず外部のストレージに保存すべしという認識はそれなりに進んでいるのではないかと思います。では具体的にどういう方法でアプリケーションログを外部に保存すればよいのでしょうか。
一つの案は、FluentdやLogstashのようなログ収集ミドルウェアを利用することです。これらのプロダクトは様々な形式のinput/outputに対応しており、柔軟な設定を行うことが可能です。
一方で、それほど高機能でなくても良い、ただ単にログを保管しておきたいだけという要望もあるかと思います。そういった場合にはlogback-kinesis-appenderのようなライブラリを使うことを検討してみてはいかがでしょうか?非常に簡単に外部へのログ送信が行なえます。
今回の検証に使ったアプリケーションはGithubに置いてあります。clone後、src/main/resources/logback.xml
のStreamNameを書き換えた後に以下のコマンドで皆様の環境でも実行可能です。お試しください。
$ cd path/to/project && ./gradlew bootRun